home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / shar.lha / shar / sysfuncs.c- < prev    next >
Text File  |  1987-12-03  |  5KB  |  265 lines

  1. /*
  2. **  System-specific stuff.  This module will need to be ported to
  3. **  other systems.
  4. */
  5. /* LINTLIBRARY */
  6. #include "shar.h"
  7. #include <signal.h>
  8. #include <pwd.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #ifdef    SYS_WAIT
  12. #include <sys/wait.h>
  13. #else
  14. #endif    /* SYS_WAIT */
  15. RCS("$Header: sysfuncs.c,v 1.7 87/03/13 13:08:34 rs Exp $")
  16.  
  17.  
  18. /* How to fork(), what to wait with. */
  19. #ifdef    SYS_WAIT
  20. #define FORK()         vfork()
  21. #define W_VAL(w)     ((w).w_retcode)
  22. typedef union wait     WAITER;
  23. #else
  24. #define FORK()         fork()
  25. #define W_VAL(w)     ((w) >> 8)
  26. typedef int         WAITER;
  27. #endif    /* SYS_WAIT */
  28.  
  29.  
  30. /* Mask of executable bits. */
  31. #define    EXE_MASK    (S_IEXEC | (S_IEXEC >> 3) | (S_IEXEC >> 6))
  32.  
  33. /* Stat buffer for last file. */
  34. static struct stat     Sb;
  35.  
  36.  
  37. /*
  38. **  Get user name.  Not secure, but who sends nastygrams as shell archives?
  39. */
  40. char *
  41. User()
  42. {
  43.     extern struct passwd    *getpwuid();
  44.     struct passwd        *p;
  45.     char            *g;
  46.  
  47.     if (g = getenv(USER_ENV))
  48.     return(g);
  49.     return((p = getpwuid(getuid())) ? p->pw_name : "USER");
  50. }
  51.  
  52.  
  53. /*
  54. **  Set up a signal handler.
  55. */
  56. SetSigs(What, Func)
  57.     int          What;
  58.     int        (*Func)();
  59. {
  60.     if (What == S_IGNORE)
  61.     Func = SIG_IGN;
  62.     else if (What == S_RESET)
  63.     Func = SIG_DFL;
  64.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  65.     (void)signal(SIGINT, Func);
  66.     if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
  67.     (void)signal(SIGQUIT, Func);
  68. }
  69.  
  70.  
  71. /*
  72. **  Stat the file if it's not the one we did last time.
  73. */
  74. int
  75. GetStat(p)
  76.     char        *p;
  77. {
  78.     static char         Name[BUFSIZ];
  79.  
  80.     if (*p == Name[0] && EQ(p, Name))
  81.     return(TRUE);
  82.     return(stat(strcpy(Name, p), &Sb) < 0 ? FALSE : TRUE);
  83. }
  84.  
  85.  
  86. /*
  87. **  Return the file type -- directory or regular file.
  88. */
  89. int
  90. Ftype(p)
  91.     char    *p;
  92. {
  93.     return(GetStat(p) && ((Sb.st_mode & S_IFMT) == S_IFDIR) ? F_DIR : F_FILE);
  94. }
  95.  
  96.  
  97. /*
  98. **  Return the file size.
  99. */
  100. off_t
  101. Fsize(p)
  102.     char    *p;
  103. {
  104.     return(GetStat(p) ? Sb.st_size : 0);
  105. }
  106.  
  107.  
  108. /*
  109. **  Is a file executable?
  110. */
  111. int
  112. Fexecute(p)
  113.     char    *p;
  114. {
  115.     return(GetStat(p) && (Sb.st_mode & EXE_MASK) ? TRUE : FALSE);
  116. }
  117.  
  118.  
  119. /*
  120. **  Return the process ID.
  121. */
  122. int
  123. Pid()
  124. {
  125.     static int     X;
  126.  
  127.     if (X == 0)
  128.     X = getpid();
  129.     return(X);
  130. }
  131.  
  132.  
  133. /*
  134. **  Return the text string that corresponds to errno.
  135. */
  136. char *
  137. Ermsg(e)
  138.     int             e;
  139. {
  140.     extern int         sys_nerr;
  141.     extern char        *sys_errlist[];
  142.     static char         buff[30];
  143.  
  144.     if (e > 0 && e < sys_nerr)
  145.     return(sys_errlist[e]);
  146.     (void)sprintf(buff, "Error code %d", e);
  147.     return(buff);
  148. }
  149.  
  150.  
  151. /*
  152. **  Fork off a command.
  153. */
  154. int
  155. Execute(av)
  156.     char        *av[];
  157. {
  158.     register int     i;
  159.     register int     j;
  160.     WAITER         W;
  161.  
  162.     if ((i = FORK()) == 0) {
  163.     SetSigs(S_RESET, (int (*)())NULL);
  164.     (void)execvp(av[0], av);
  165.     perror(av[0]);
  166.     _exit(1);
  167.     }
  168.  
  169.     SetSigs(S_IGNORE, (int (*)())NULL);
  170.     while ((j = wait(&W)) < 0 && j != i)
  171.     ;
  172.     SetSigs(S_RESET, (int (*)())NULL);
  173.     return(W_VAL(W));
  174. }
  175.  
  176.  
  177. #ifdef    NEED_MKDIR
  178. /*
  179. **  Quick and dirty mkdir routine for them that's need it.
  180. */
  181. int
  182. mkdir(name, mode)
  183.     char    *name;
  184.     int         mode;
  185. {
  186.     char    *av[3];
  187.     int         i;
  188.  
  189.     av[0] = "mkdir";
  190.     av[1] = name;
  191.     av[2] = NULL;
  192.     U = umask(~mode);
  193.     i = Execute(av);
  194.     (void)umask(U);
  195.     return(i ? -1 : 0);
  196. }
  197. #endif    /* NEED_MKDIR */
  198.  
  199.  
  200. #ifdef    NEED_QSORT
  201. /*
  202. **  Bubble sort an array of arbitrarily-sized elements.  This routine
  203. **  can be used as an (inefficient) replacement for the Unix qsort
  204. **  routine, hence the name.  If I were to put this into my C library,
  205. **  I'd do two things:
  206. **    -Make it be a quicksort;
  207. **    -Have a front routine which called specialized routines for
  208. **     cases where Width equals sizeof(int), sizeof(char *), etc.
  209. */
  210. qsort(Table, Number, Width, Compare)
  211.     register char     *Table;
  212.     register int      Number;
  213.     register int      Width;
  214.     register int    (*Compare)();
  215. {
  216.     register char     *i;
  217.     register char     *j;
  218.  
  219.     for (i = &Table[Number * Width]; (i -= Width) >= &Table[Width]; )
  220.     for (j = i; (j -= Width) >= &Table[0]; )
  221.         if ((*Compare)(i, j) < 0) {
  222.         register char    *p;
  223.         register char    *q;
  224.         register int     t;
  225.         register int     w;
  226.  
  227.         /* Swap elements pointed to by i and j. */
  228.         for (w = Width, p = i, q = j; --w >= 0; *p++ = *q, *q++ = t)
  229.             t = *p;
  230.         }
  231. }
  232. #endif    /* NEED_QSORT */
  233.  
  234.  
  235. #undef NOTDEF
  236. #ifdef    NOTDEF
  237. /*
  238. **  Cons all the arguments together into a single command line and hand
  239. **  it off to the shell to execute.  This is only here for someone to use
  240. **  as the basis of, say, an MSDOS port.
  241. */
  242. int
  243. Execute(av)
  244.     register char    *av[];
  245. {
  246.     register char    **v;
  247.     register char     *p;
  248.     register char     *q;
  249.     register int     i;
  250.  
  251.     /* Get length of command line. */
  252.     for (i = 5, v = av; *v; v++)
  253.     i += strlen(*v) + 1;
  254.  
  255.     /* Create command line and execute it. */
  256.     p = NEW(char, i);
  257.     for (q = p + strlen(strcpy(p, "exec")), v = av; *v; v++) {
  258.     *q++ = ' ';
  259.     q += strlen(strcpy(q, *v));
  260.     }
  261.  
  262.     return(system(p));
  263. }
  264. #endif    /* NOTDEF */
  265.